/*
 * ECU_SBC4500.c
 *
 *  Created on: 2018年12月17日
 *      Author: 40786
 */

#include 	"main.h"

uint16 modedata;
uint16 InitSPI_ERR;

u16 data631[8];
u16 data632[8];
lpspi_tx_cmd_config_t SBC4500_Lpspi_TxCfg =
{
	.whichPcs = LPSPI_PCS1,							/* PCS=1: Transfer using PCS1 */
	.width = LPSPI_SINGLE_BIT_XFER,					/* WIDTH=0: Single bit transfer */
	.clkPhase = LPSPI_CLOCK_PHASE_2ND_EDGE,			/* CPHA=0: Change data on SCK lead'g, capture on trail'g edge*/
	.clkPolarity = LPSPI_SCK_ACTIVE_HIGH,			/* CPOL=0: SCK inactive state is HIGH */
	.lsbFirst = false,								/* LSBF=0: Data is transfered MSB first */
	.txMask 	= false,							/* TXMSK=0: Normal transfer: data loaded from tx FIFO */
	.rxMask		= false,							/* RXMSK=0: Normal transfer: rx data stored in rx FIFO */
	.contTransfer = true,							/* CONTC=0: Continuous transfer disabled */
	.contCmd = false ,								/* Master option to change cmd word within cont transfer. */
	.frameSize = 16,								/* FRAMESZ=7: # bits in frame = 7+1=8 */
	.preDiv    = 1,									/* PRESCALE=2: Functional clock divided by 2*2 = 4 */
	.byteSwap = false, 								/* BYSW=0: Byte swap disabled */
};



Bsw_Lpspi_Cfg 	SBC4500_LPSPI0_Cfg =
{
	.base = LPSPI0,									/*SPI硬件模块选择:  LPSPI0*/
	.clockName = LPSPI0_CLK,
	.clockSource = 6,
	.b_TxDmaCmd = false ,							/* TXDMA not used */
	.b_RxDmaCmd = false ,							/* RXDMA not used */
	.Lpspi_mode = LPSPI_MASTER,						/* Set for master mode */

	.PinCfg = LPSPI_SDI_IN_SDO_OUT,
	.DataOutCfg = LPSPI_DATA_OUT_RETAINED,
	.b_Pcs_Enable = true,
	.b_SampleDly = 	false,
	.txWater = 1,
	.rxWater = 0,
	.Cmd_Cfg = &SBC4500_Lpspi_TxCfg,
	.u32_SCKDIV = 8,
	.u32_SCKPCS = 20,
	.u32_PCSSCK = 20,
	.u32_DBT = 20,
	.Lpspi_Pcs = LPSPI_PCS1,
  .PcsPolarity = LPSPI_ACTIVE_LOW,
};

CommandType SBC_INIT_VREG_Command = 	/* bit7: ICCA_LIM		0: ICCA_LIM_OUT 		       					*/
{										/* bit6: TCCA_LIM_OFF	1: 50ms        		 		 					*/
	Common,								/* bit5: IPFF_DIS		0: Enabled					 					*/
	{									/* bit4: VCAN_OV_MON	1: On					     					*/
			0X00//0x54						/* bit3:           		0												*/
	}									/* bit2: TAUX_LIM_OFF	1: 50ms 				 					    */
										/* bit1: VAUX_TRK_EN	0: NO tracking			            			*/
};										/* bit0:          		0        										*/

CommandType SBC_INIT_WU1_Command =		/* bit7-6: WU_IO0 		01: Wake-up on rising edge - or high level	KL15*/
{										/* bit5-4: WU_IO2		00: NO wake-up capability						*/
	Common,								/* bit3-2: WU_IO3		01: Wake-up on rising edge - or high level	CAN	*/
	{									/* bit3-2: WU_IO4		01: Wake-up on rising edge - or high level	RTC	*/
			0x40
	}

};

CommandType SBC_INIT_WU2_Command =		/* bit7-6: WU_IO5 		01: Wake-up on rising edge - or high level			33771*/
{										/* bit5: CAN_DIS_CFG 	 0: CAN in Rx only mode						FS1B Not Used*/
	Common,								/* bit4: CAN_WU_TO 		 0: 120μs										Not Used */
	{									/* bit3:           		 0														 */
			0x00						/* bit2: LIN_J2602_dis   0: Compliant with J2602 standard(Default)		Not Used */
	}									/* bit1-0: LIN_SR_1:0   00: 20 kbits/s									Not Used */

};

CommandType SBC_INIT_INT_Command =		/* bit7: INT_DURATION 		0: 100μs											*/
{										/* bit6: INT_INH_LIN 		1: LIN error bits change INHIBITED			Not Used*/
	Common,								/* bit5: INT_INH_ALL 		0: All INT sources									*/
	{									/* bit4: INT_INH_VSNS 		0: All INT sources							 		*/
			0x00//0x40						/* bit3: INT_INH_VPRE 		0: All INT sources							 		*/
	}									/* bit2: INT_INH_VCORE 		0: All INT sources							 		*/
										/* bit1: INT_INH_VOTHER 	0: All INT sources							 		*/
};										/* bit0: INT_INH_CAN 		0: All INT sources							 		*/

CommandType SBC_INIT_INH_INT_Command =	/* bit7-5:           		000:												 */
{										/* bit4:INT_INH_5           0:INT not masked									 */
	Common,								/* bit3:INT_INH_4 	        0:INT not masked									 */
	{									/* bit2:INT_INH_3           1:INT masked										 */
			0x00//0x06						/* bit1:INT_INH_2           1:INT masked										 */
	}									/* bit0:INT_INH_0           0:INT not masked									 */

};

CommandType SBC_LONG_DURATION_TIMER_Command =	/* bit7-5: F2:F0           100:Function 5										 */
{												/* bit4: REG_SE           	 0:Read programmed wake-up register					 */
	Common,										/* bit3:            	 	 0:													 */
	{											/* bit2: MODE           	 1:Normal mode (1 s resolution)						 */
			0x96								/* bit1: LDT_ENABLE          1:LDT counter Start									 */
	}											/* bit0: 			         0:													 */

};

CommandType SBC_MODE_Command =			/* bit7: VKAM_EN          		 0:DISABLED								 		*/
{										/* bit6: LPOFF_AUTO_WU           0:No action								 	*/
	Secure,								/* bit5: GO_LPOFF          		 0:No action								 	*/
	{									/* bit4: INT_REQ          		 0:No Request								 	*/
			0x00						/* bit3-0: Secure3-0          0000								 				*/
	}

};

CommandType SBC_REG_MODE_Command =		/* bit7: VCORE_EN          		 1:Enabled								 		*/
{										/* bit6: VCCA_EN          		 1:Enabled								 		*/
	Secure,								/* bit5: VAUX_EN          		 1:Enabled								 		*/
	{									/* bit4: VAUX_EN          		 1:Enabled								 		*/
			0x80						/* bit3-0: Secure3-0          0000								 				*/
	}

};

CommandType SBC_IO_OUT_AMUX_Command =	/* bit7: IO_OUT_4_EN          	 0:High-impedance (IO_4 configured as input)	*/
{										/* bit6: IO_OUT_4          		 0:Low(Default)									*/
	Common,								/* bit5-3:         			   000								 				*/
	{									/* bit2-0:         			   000:VREF						 					*/
			0x00
	}

};

CommandType SBC_CAN_LIN_MODE_Command =	/* bit7-6: CAN_MODE_1:0         11:Normal operation mode 						*/
{										/* bit5: CAN_AUTO_DIS          	 1:Reset CAN_mode from ’11’ to ’01’ 			*/
	Common,								/* bit4-3: LIN_MODE_1:0         10:(Default)			 				Not Used*/
	{									/* bit2: LIN_AUTO_DIS         	 1:(Default)			 				Not Used*/
			0xF4						/* bit1-0:          	 		00						 				Not Used*/
	}

};

CommandType SBC_LDT_AFTER_RUN_1_Command =	/* bit7-0: B15:8      0:After run value (8 most significant bits) (Default)*/
{
	Common,
	{
			0x00
	}

};

CommandType SBC_LDT_AFTER_RUN_2_Command =	/* bit7-0: B7:0      0:After run value (8 least significant bits) (Default)*/
{
	Common,
	{
			0x00
	}

};

CommandType SBC_LDT_WAKE_UP_1_Command =		/* bit7-0: B23:16      0:Wake-up value (8 most significant bits) (Default)*/
{
	Common,
	{
			0xFF
	}

};

CommandType SBC_LDT_WAKE_UP_2_Command =		/* bit7-0: B15:8      0:Wake-up value (8 intermediate bits) (Default)	*/
{
	Common,
	{
			0x00
	}

};

CommandType SBC_LDT_WAKE_UP_3_Command =		/* bit7-0: B7:0   0:Wake-up value (8 least significant bits) (Default)*/
{
	Common,
	{
			0x00
	}

};

/*---------Fail-safe logic register-------*/

CommandType SBC_INIT_FS1B_TIMING_Command =	/* bit7-4: FS1B_TIME_3:0     0110:37ms  					 (Default)*/
{											/* bit3-0: Secure3:0	     0000:		  					 (Default)*/
	Secure,
	{
			0x60
	}

};

CommandType SBC_BIST_Command =		/* bit7: 		    			0:		  					 		*/
{									/* bit6:ABIST2_FS1B    			1:Launch ABIST on FS1B		  		*/
	Secure,							/* bit5:ABIST2_VAUX    			1:Launch ABIST on VAUX	  			*/
									/* bit4: 		    			0:		  					 		*/
	{								/* bit3-0: Secure3:0	     0000:		  				   (Default)*/
			0x60
	}

};

CommandType SBC_INIT_SUPERVISOR_Command =	/* bit7:VCORE_5D    			0:detection threshold (VCORE_FB_UV) 		*/
{											/* bit6:VCCA_5D	    			0:detection threshold (VCCA_UV_5) 			*/
	Secure,									/* bit5:VAUX_5D	    			0:detection threshold (VAUX_UV_5) 			*/
	{										/* bit4:FS1B_TIME_RANGE	    	0:x1 timing range factor		 			*/
			0x00							/* bit3-0: Secure3:0	     0000:		  				   		   (Default)*/
	}

};

CommandType SBC_INIT_FAULT_Command =		/* bit7:FLT_ERR_FS    		0:intermediate = 3; final = 6		 						*/
{											/* bit6:FS1B_CAN_IMPACT		1:CAN in Rx only or sleep mode when FS1B is asserted 		*/
	Secure,									/* bit5-4:FLT_ERR_IMP_1:0  01:FS0B is asserted low if FLT_ERR_CNT ≥ intermediate value  */
	{										/* bit3-0: Secure3:0	 0000:		  				   		 				   (Default)*/
			0x50
	}

};

CommandType SBC_INIT_FSSM_Command =		/* bit7:IO_45_FS    		0:Not safety		 						*/
{										/* bit6:IO_23_FS    		1:Safety critical		 		   (Default)*/
	Secure,								/* bit5:PS    				0:Fccu_eaout_1:0 active high	   (Default)*/
	{									/* bit4:RSTB_DURATION		0:10ms							   (Default)*/
			0x40						/* bit3-0: Secure3:0	 0000:		  				   		   (Default)*/
	}

};

CommandType SBC_INIT_SF_IMPACT_Command =	/* bit7:TDLY_TDUR    		0:FS1B tDELAY mode		 			(Default)*/
{											/* bit6:DIS_8S    			0:Enabled		 					(Default)*/
	Secure,									/* bit5-4:WD_IMPACT_1:0    01:RSTB only is asserted low if WD error counter = WD_CNT_ERR[1:0]	(Default)*/
	{										/* bit3-0: Secure3:0	 0000:		  				   		   (Default)*/
			0x10
	}

};

CommandType SBC_WD_WINDOW_Command =		/* bit7-4: WD_WINDOW_3:0	 1101:		  	256ms			   		   		*/
{										/* bit3-0: Secure3:0	 	 0000:		  				   		   (Default)*/
	Secure,
	{
			0xD0
	}

};

CommandType SBC_WD_LFSR_Command =		/* bit7-0: WD_LFSR_7:0		 1011 0010:		  	0xB2			   (Default) */
{
	Common,
	{
			0xB2
	}

};

CommandType SBC_WD_ANSWER_Command =		/* bit7-0: WD_ANSWER_7:0		 0000 0000:		  	0x00			   (Default) */
{
	Common,
	{
			0x00
	}

};

CommandType SBC_RELEASE_FSxB_Command =	/* bit7-0: RELEASE_FSxB_7:0		 0000 0000:		  	0x00			   (Default) */
{
	Common,
	{
			0x00
	}

};

CommandType SBC_SF_OUTPUT_REQUEST_Command =		/* bit7: FS1B_REQ			 0:No request				  		  (Default)*/
{												/* bit6: FS1B_DLY_REQ		 1:open S1						   	 		   */
	Secure,										/* bit5: FS0B_REQ		 	 0:No request					   	 		   */
	{											/* bit4: RSTB_REQ		 	 0:No request					   	 		   */
			0x00								/* bit3-0: Secure3:0	  0000:		  				   		   	  (Default)*/
	}

};

CommandType SBC_INIT_WD_CNT_Command =		/* bit7-6: WD_CNT_ERR_1:0		00:6				  				  (Default)*/
{											/* bit5-4: WD_CNT_RFR_1:0		00:6				  				  (Default)*/
	Secure,									/* bit3-0: Secure3:0	      0000:		  				   		   	  (Default)*/
	{
			0x00
	}

};

CommandType SBC_INIT_VCORE_OVUV_IMPACT_Command =	/* bit7-6: VCORE_FS_OV_1:0	11:VCORE_FB_OV does have an impact on RSTB and FS0B	  (Default)*/
{													/* bit5-4: VCORE_FS_UV_1:0	10:VCORE_FB_UV does have an impact on FS0B only	  	  (Default)*/
	Secure,											/* bit3-0: Secure3:0	  0000:		  				   		   					  (Default)*/
	{
			0xE0
	}

};

CommandType SBC_INIT_VCCA_OVUV_IMPACT_Command =		/* bit7-6: VCCA_FS_OV_1:0	11:VCCA_OV does have an impact on RSTB and FS0B	 	 (Default)*/
{													/* bit5-4: VCCA_FS_UV_1:0	10:VCCA_UV does have an impact on FS0B only	  	 	 (Default)*/
	Secure,											/* bit3-0: Secure3:0	  0000:		  				   		   					 (Default)*/
	{
			0xE0
	}

};

CommandType SBC_INIT_VAUX_OVUV_IMPACT_Command =		/* bit7-6: VAUX_FS_OV_1:0	11:VAUX_OV does have an impact on RSTB and FS0B	 	 (Default)*/
{													/* bit5-4: VAUX_FS_UV_1:0	10:VAUX_UV does have an impact on FS0B only	  	 	 (Default)*/
	Secure,											/* bit3-0: Secure3:0	  0000:		  				   		   					 (Default)*/
	{
			0xE0
	}

};

/*************************************************************************
 * Function Name	: ECU_SBC4500_PORT_INIT
 *
 * Description		: SBC4500端口配置
 *
 * Input			: void
 *
 * Output			: void
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
void ECU_SBC4500_PORT_INIT(void)
{
	BSW_GPIO_MUX_CONFIG(Bsw_Port_B,2,PORT_MUX_ALT3);			/* 	PB2: 	MUX = ALT3, LPSPI0_SCK 	*/
	BSW_GPIO_MUX_CONFIG(Bsw_Port_B,3,PORT_MUX_ALT3);			/* 	PB3: 	MUX = ALT3, LPSPI0_SIN 	*/
	BSW_GPIO_MUX_CONFIG(Bsw_Port_B,4,PORT_MUX_ALT3);			/* 	PB4: 	MUX = ALT3, LPSPI0_SOUT */
	BSW_GPIO_MUX_CONFIG(Bsw_Port_B,5,PORT_MUX_ALT3);			/* 	PB5: 	MUX = ALT3, LPSPI0_PCS1 */

	BSW_LPSPI_INIT(SBC4500_LPSPI0_Cfg);


}

#if 0
uint16_t SBC4500_Write_Command(u8 Address , CommandType Command)
{
	bool Parity;
	uint8_t sum;
	uint8_t SBC_WriteByte_H = 0;
	uint8_t i = 0;
	uint8_t SBC_WriteByte_L = 0;
	uint8_t SBC_Command_bit0 = 0;
	uint8_t SBC_Command_bit1 = 0;
	uint8_t SBC_Command_bit2 = 0;
	uint8_t SBC_Command_bit3 = 0;
	uint16_t SBCData = 0;
	uint16_t SBC_WriteWord = 0,Parity_data;
	/*组建命令高字节*/
	SBC_WriteByte_H = (uint8_t)(((Address << 1) | 0x80));
	/*组建命令低字节*/
	if(Secure == Command.SecureTpye)
	{
		Command.Command.DataFld &= 0xF0;  /*避免配置参数时0~3bit误写*/
		SBC_Command_bit0 = Command.Command.Bits.bit6;
		SBC_Command_bit1 = Command.Command.Bits.bit7;
		SBC_Command_bit2 = ((~Command.Command.Bits.bit4) & 0x01);
		SBC_Command_bit3 = ((~Command.Command.Bits.bit5) & 0x01);
		SBC_WriteByte_L = Command.Command.DataFld | (SBC_Command_bit3 << 3) | (SBC_Command_bit2 << 2) | (SBC_Command_bit1 << 1) | SBC_Command_bit0;
	}
	else
	{
		SBC_WriteByte_L = Command.Command.DataFld;
	}

	Parity_data=SBC_WriteWord = (uint16_t)((SBC_WriteByte_H << 8) | SBC_WriteByte_L);
     for(i=0;i<16;i++)
     {
    	 if(i!=8)
    	 {
    		 sum=sum+((Parity_data ) & 0x0001);
    	 }
    	 Parity_data>>1;
     }

     if(sum%2 == 0)
     {			//even number -> P = 1
    	 SBC_WriteWord=SBC_WriteWord|0x0100;
     }else{
    	 SBC_WriteWord=SBC_WriteWord&0xFEFF;
     }

	BSW_LPSPI_START(LPSPI0,SBC_WriteWord);
	SBCData=BSW_LPSPI_END(LPSPI0);
	return SBCData;
}
#endif
/*************************************************************************
 * Function Name	: SBC4500_Read_Command
 *
 * Description		: 读取SBC4500寄存器指令
 *
 * Input			: u8 Address
 *
 * Output			: uint16_t  SBCData
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Read_Command(u8 Address)
{
	uint8_t SBC_WriteByte_H = 0;
	uint16_t SBCData = 0;
	uint16_t SBC_WriteWord = 0;
	/*组建命令高字节*/
	SBC_WriteByte_H = (uint8_t)((Address << 1) & 0x7E);	/*清除最高位和校验位*/
	SBC_WriteWord = (uint16_t)((SBC_WriteByte_H << 8) & 0xFF00);/*清除低字节*/

	BSW_LPSPI_START(LPSPI0,SBC_WriteWord);
	SBCData=BSW_LPSPI_END(LPSPI0);
	return SBCData;
}


/*************************************************************************
 * Function Name	: SBC4500_WD_Refresh
 *
 * Description		: SBC4500端口配置
 *
 * Input			: void
 *
 * Output			: uint16_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_WD_Refresh(void)
{
	uint16_t LFSR_Data	= 0;
	uint16_t Random		= 0;
	uint16_t Return_Data = 0;
	data631[7]=LFSR_Data = SBC4500_Read_Command(SBC_WD_LFSR);
	Random = (~(((LFSR_Data & 0x00ff) <<2) + 2))>>2;

//	Random=Random-1;
//	SBC_WD_ANSWER_Command.Command.DataFld = (uint8_t)Random;
//	data631[3]=Random;
	Return_Data = SBC4500_Write_data(SBC_WD_ANSWER,(uint8_t)Random,0);
	return Return_Data;
}


/*************************************************************************
 * Function Name	: SBC4500_Release_FS0B
 *
 * Description		: SBC4500 FS0B 释放
 *
 * Input			: void
 *
 * Output			: uint16_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Release_FS0B(void)
{
	uint16_t LFSR_Data		 = 0;
	uint8_t  ReleaseFS0B_Key = 0x60;
	uint16_t Return_Data 	 = 0;
	LFSR_Data = SBC4500_Read_Command(SBC_WD_LFSR);
	SBC_RELEASE_FSxB_Command.Command.DataFld = (uint8_t)LFSR_Data;

	ReleaseFS0B_Key = ReleaseFS0B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit0) & 0x01) << 4);
	ReleaseFS0B_Key = ReleaseFS0B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit1) & 0x01) << 3);
	ReleaseFS0B_Key = ReleaseFS0B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit2) & 0x01) << 2);
	ReleaseFS0B_Key = ReleaseFS0B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit3) & 0x01) << 1);
	ReleaseFS0B_Key = ReleaseFS0B_Key | ((~SBC_RELEASE_FSxB_Command.Command.Bits.bit4) & 0x01);

	SBC_RELEASE_FSxB_Command.Command.DataFld = ReleaseFS0B_Key;
	Return_Data =SBC4500_Write_data(SBC_RELEASE_FSxB,ReleaseFS0B_Key,0);
//	Return_Data = SBC4500_Write_Command(SBC_RELEASE_FSxB,SBC_RELEASE_FSxB_Command);
	return Return_Data;
}


/*************************************************************************
 * Function Name	: SBC4500_Release_FS1B
 *
 * Description		: SBC4500 FS1B 释放
 *
 * Input			: void
 *
 * Output			: uint16_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Release_FS1B(void)
{
//	uint16_t LFSR_Data		 = 0;
//	uint8_t  ReleaseFS1B_Key = 0xC0;
	uint16_t Return_Data 	 = 0;
//	LFSR_Data = SBC4500_Read_Command(SBC_WD_LFSR);
//	SBC_RELEASE_FSxB_Command.Command.DataFld = (uint8_t)LFSR_Data;

//	ReleaseFS1B_Key = ReleaseFS1B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit3) & 0x01) << 4);
//	ReleaseFS1B_Key = ReleaseFS1B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit4) & 0x01) << 3);
//	ReleaseFS1B_Key = ReleaseFS1B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit5) & 0x01) << 2);
//	ReleaseFS1B_Key = ReleaseFS1B_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit6) & 0x01) << 1);
//	ReleaseFS1B_Key = ReleaseFS1B_Key | ((~SBC_RELEASE_FSxB_Command.Command.Bits.bit7) & 0x01);

//	SBC_RELEASE_FSxB_Command.Command.DataFld = ReleaseFS1B_Key;
//	Return_Data = SBC4500_Write_Command(SBC_RELEASE_FSxB,SBC_RELEASE_FSxB_Command);
	return Return_Data;
}


/*************************************************************************
 * Function Name	: SBC4500_Release_FSxB
 *
 * Description		: SBC4500 FS1B FS0B 释放
 *
 * Input			: void
 *
 * Output			: uint16_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Release_FSxB(void)
{
	uint16_t LFSR_Data		 = 0;
	uint8_t  ReleaseFSxB_Key = 0xA0;
	uint16_t Return_Data 	 = 0;
	LFSR_Data = SBC4500_Read_Command(SBC_WD_LFSR);
	SBC_RELEASE_FSxB_Command.Command.DataFld = (uint8_t)LFSR_Data;

	ReleaseFSxB_Key = ReleaseFSxB_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit0) & 0x01) << 4);
	ReleaseFSxB_Key = ReleaseFSxB_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit1) & 0x01) << 3);
	ReleaseFSxB_Key = ReleaseFSxB_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit2) & 0x01) << 2);
	ReleaseFSxB_Key = ReleaseFSxB_Key | (((~SBC_RELEASE_FSxB_Command.Command.Bits.bit6) & 0x01) << 1);
	ReleaseFSxB_Key = ReleaseFSxB_Key | ((~SBC_RELEASE_FSxB_Command.Command.Bits.bit7) & 0x01);

	SBC_RELEASE_FSxB_Command.Command.DataFld = ReleaseFSxB_Key;

	Return_Data =SBC4500_Write_data(SBC_RELEASE_FSxB,ReleaseFSxB_Key,0);

	return Return_Data;

}


/*************************************************************************
 * Function Name	: SBC4500_Go_Sleep
 *
 * Description		: SBC4500 进入Sleep模式
 *
 * Input			: void
 *
 * Output			: uint16_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Go_Sleep(void)
{
	uint16_t Return_Data 	 = 0;

	SBC4500_Write_data(SBC_CAN_LIN_MODE,0x10,0);//CAN为normal模式

	Return_Data =SBC4500_Write_data(SBC_MODE,0x20,1);
//	Return_Data = SBC4500_Write_Command(SBC_MODE,SBC_MODE_Command);

	return Return_Data;
}


/*************************************************************************
 * Function Name	: SBC4500_Clear_DiagFlag
 *
 * Description		: SBC4500 清除所有诊断标志位
 *
 * Input			: void
 *
 * Output			: uint16_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Clear_DiagFlag(void)
{
	uint16_t Return_Data 	 = 0;
	uint16_t tempdata 		 = 0;
	data631[0] = SBC4500_Read_Command(SBC_DIAG_VPRE);
	data631[1] = SBC4500_Read_Command(SBC_DIAG_VCORE);
	data631[2] = SBC4500_Read_Command(SBC_DIAG_VCCA);
	data631[3] = SBC4500_Read_Command(SBC_DIAG_VAUX);
	tempdata = SBC4500_Read_Command(SBC_DIAG_VSUP_VCAN);
	tempdata = SBC4500_Read_Command(SBC_DIAG_CAN_FD);
	tempdata = SBC4500_Read_Command(SBC_DIAG_CAN_LIN);
	data631[4] = SBC4500_Read_Command(SBC_DIAG_SPI);
	data631[5] = SBC4500_Read_Command(SBC_DIAG_SF_IOs);
	data631[6] = SBC4500_Read_Command(SBC_DIAG_SF_ERR);

	return Return_Data;
}


/*************************************************************************
 * Function Name	: SBC4500_Start_RTC
 *
 * Description		: SBC4500 启动RTC
 *
 * Input			: void
 *
 * Output			: uint16_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Start_RTC(void)
{
	uint16_t Return_Data 	 = 0;
	SBC4500_Write_data(SBC_LONG_DURATION_TIMER ,0x84,0);//7:5 F 功能设置 工嗯呢该5   4：REG_SE  2:MODE  1：LDT_ENABLE
	APPL_Delay_us(100);
	SBC4500_Write_data(SBC_LDT_WAKE_UP_1 ,0xFF,0);//B23-B16
	SBC4500_Write_data(SBC_LDT_WAKE_UP_2 ,0xFF,0);//B15-B8
	SBC4500_Write_data(SBC_LDT_WAKE_UP_3 ,0xFF,0);//B7-B0
	APPL_Delay_us(100);
	SBC4500_Read_Command(SBC_LDT_WAKE_UP_1) ;
    SBC4500_Read_Command(SBC_LDT_WAKE_UP_2);
	SBC4500_Read_Command(SBC_LDT_WAKE_UP_3);
	APPL_Delay_us(100);
	SBC4500_Write_data(SBC_LONG_DURATION_TIMER ,0x96,0);//7:5 F 功能设置 工嗯呢该5   4：REG_SE  2:MODE  1：LDT_ENABLE
	APPL_Delay_us(100);
	return Return_Data;
}


/*************************************************************************
 * Function Name	: SBC4500_Read_RTC
 *
 * Description		: SBC4500 读取RTC
 *
 * Input			: void
 *
 * Output			: uint32_t  Return_Data
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint32_t SBC4500_Read_RTC(void)
{
	uint32_t Return_Data 	 = 0;
	SBC4500_Write_data(SBC_LONG_DURATION_TIMER ,0x84,0);//7:5 F 功能设置 工嗯呢该5   4：REG_SE  2:MODE  1：LDT_ENABLE 停止
	SBC4500_Write_data(SBC_LONG_DURATION_TIMER ,0x94,0);//7:5 F 功能设置 工嗯呢该5   4：REG_SE  2:MODE  1：LDT_ENABLE 停止
	APPL_Delay_us(300);
	Return_Data = (SBC4500_Read_Command(SBC_LDT_WAKE_UP_1) & 0xFF);
	Return_Data = (Return_Data << 8) + (SBC4500_Read_Command(SBC_LDT_WAKE_UP_2) & 0xFF);
	Return_Data = (Return_Data << 8) + (SBC4500_Read_Command(SBC_LDT_WAKE_UP_3) & 0xFF);

	return Return_Data;
}



/*************************************************************************
 * Function Name	: SBC4500_Init
 *
 * Description		: SBC4500初始化
 *
 * Input			: void
 *
 * Output			: void
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
void SBC4500_Init(void)
{
	uint16_t tempdata = 0,testdata;
	uint8_t	 Fail_Safe_State = 0;
	ECU_SBC4500_PORT_INIT();
//	SBC4500_Write_data(SBC_INIT_WU1,0x40,0);
#if (ON == Fail_Safe)
	/*------POR Verify------*/
	if(0x09 == (SBC4500_Read_Command(SBC_BIST) & 0x09))	/*Verify LBIST and ABIST1 are pass */
	{
		if(0x26 == (SBC4500_Read_Command(SBC_HW_CONFIG) & 0xBF))  /*Verify HardWare configuration；VPRE、VCCA、VAUX、DEBUG Mode、Deep FS cfg */
		{
			Fail_Safe_State = 1;
		}
		else
		{
			Fail_Safe_State = 0;
		}
	}
	else
	{
		Fail_Safe_State = 0;
	}
#else
	 Fail_Safe_State = 1;
#endif

	if(1 == Fail_Safe_State)
	{
		SBC4500_Read_Command(SBC_DEVICE_ID);
		SBC4500_Read_Command(SBC_BIST);//读取LBIST及ABIST1检测状态
		SBC4500_Read_Command(SBC_INIT_VREG); //读取VREG状态
		SBC4500_Write_data(SBC_INIT_WU1,0x40,0);/*唤醒源设置    7:6 IO0    5:4  IO2  3:2 IO3  1:0 IO4*/
		SBC4500_Write_data(SBC_INIT_WU2,0x00,0);
		SBC4500_Read_Command(SBC_INIT_WU2);
		SBC4500_Write_data(SBC_INIT_FSSM,0x00,1); //  关闭FCCM

		SBC4500_Write_data(SBC_INIT_FAULT,0x10,1); //设置fault error counter，设置FS1B拉低后CAN动作  设置fault error counter超过3次后的动作


		SBC4500_Write_data(SBC_INIT_VAUX_OVUV_IMPACT,0x00,1);
		SBC4500_Write_data(SBC_INIT_INH_INT,0x00,0);
		SBC4500_Write_data(SBC_WD_WINDOW,0xD0,1);//设置看门狗时间
		SBC4500_Read_Command(SBC_WD_WINDOW);
		SBC4500_Write_data(SBC_INIT_INT,0x00,0);//主状态机进入NORMAL模式


//		SBC4500_Read_Command(SBC_DIAG_SPI);
		SBC4500_Write_data(SBC_IO_OUT_AMUX,0x01,0);//设置IO4输入状态  设置MUX输出选择
//		InitSPI_ERR=SBC4500_Read_Command(SBC_DIAG_SPI);
//		modedata=SBC4500_Read_Command(SBC_MODE);
		SBC4500_Read_Command(SBC_HW_CONFIG);//读取BUCK_boost模式  读取每个电源输出值   3.3or5V
		SBC4500_Write_data(SBC_CAN_LIN_MODE,0xF4,0);//CAN为normal模式
		SBC4500_Write_data(SBC_BIST,0x60,1); //ABIST2 检测执行
		data632[4]=SBC4500_Read_Command(SBC_WD_COUNTER);


		SBC4500_Write_data(SBC_REG_MODE,0xD0,1);

	    SBC4500_Clear_DiagFlag(); //清除DIAG里面所有故障
	    SBC4500_WD_Refresh(); //喂狗   安全状态机进入Noemal模式
		//SBC4500_Release_FS0B();

       #if 0
		/*Configure VCORE, VCCA, and VAUX overvoltage and undervoltage impact on RSTB and FS0B*/
		tempdata = SBC4500_Write_Command(SBC_INIT_VCORE_OVUV_IMPACT,SBC_INIT_VCORE_OVUV_IMPACT_Command);
		tempdata = SBC4500_Write_Command(SBC_INIT_VCCA_OVUV_IMPACT,SBC_INIT_VCCA_OVUV_IMPACT_Command);
		tempdata = SBC4500_Write_Command(SBC_INIT_VAUX_OVUV_IMPACT,SBC_INIT_VAUX_OVUV_IMPACT_Command);
		/*Configure VAUX as tracker of VCCA if using VAUX to supply sensors and VCCA as an MCU ADC reference voltage*/
		tempdata = SBC4500_Write_Command(SBC_INIT_VREG,SBC_INIT_VREG_Command);
		/*Configure the WD window period and the WD counters*/
		tempdata = SBC4500_Write_Command(SBC_WD_WINDOW,SBC_WD_WINDOW_Command);
		tempdata = SBC4500_Write_Command(SBC_INIT_WD_CNT,SBC_INIT_WD_CNT_Command);
		/*Configure the WD impact on RSTB and FS0B*/
		tempdata = SBC4500_Write_Command(SBC_INIT_SF_IMPACT,SBC_INIT_SF_IMPACT_Command);
		/*Configure the final and indirectly intermediate value of the fault error counter*/
		/*Configure RSTB and FS0B behavior when fault error counter ≥ intermediate value*/
		tempdata = SBC4500_Write_Command(SBC_INIT_FAULT,SBC_INIT_FAULT_Command);
		/*Configure the RSTB pulse duration*/
		tempdata = SBC4500_Write_Command(SBC_INIT_FSSM,SBC_INIT_FSSM_Command);
		/*Configure IO*/
		tempdata = SBC4500_Write_Command(SBC_INIT_WU1,SBC_INIT_WU1_Command);
		tempdata = SBC4500_Write_Command(SBC_INIT_WU2,SBC_INIT_WU2_Command);
		tempdata = SBC4500_Write_Command(SBC_INIT_INH_INT,SBC_INIT_INH_INT_Command);
		/*Configure FS1B mode (TDELAY or TDUR) and its associated timing.*/
		tempdata = SBC4500_Write_Command(SBC_INIT_SUPERVISOR,SBC_INIT_SUPERVISOR_Command);
		tempdata = SBC4500_Write_Command(SBC_INIT_FS1B_TIMING,SBC_INIT_FS1B_TIMING_Command);
		/*Execute ABIST2 on FS1B and VAUX*/
		tempdata = SBC4500_Write_Command(SBC_BIST,SBC_BIST_Command);
		/*Close the Fail-safe INIT phase*/
		tempdata = SBC4500_WD_Refresh();
		/*Configure and Close the Main INIT phase*/
		tempdata = SBC4500_Write_Command(SBC_INIT_INT,SBC_INIT_INT_Command);
		/*Clear all the flags*/
		tempdata = SBC4500_Clear_DiagFlag();
		/*Clear the fault error counter to “0”*/

		/*Close the switch S1 when FS1B is used*/
		tempdata = SBC4500_Write_Command(SBC_SF_OUTPUT_REQUEST,SBC_SF_OUTPUT_REQUEST_Command);
		/*Release FS0B and FS1B pins*/
		SBC4500_Release_FSxB();
        #endif

	}

}
void SBC4500_OFFPOWER(void)
{
//	uint16 data;
//	data=SBC4500_Write_Command(SBC_REG_MODE,SBC_REG_MODE_Command);
}
uint16 SPI0_Writedata(uint16 data)
{
	uint16 SBCData;
	BSW_LPSPI_START(LPSPI0,data);
	SBCData=BSW_LPSPI_END(LPSPI0);
	return SBCData;

}



uint16_t SBC4500_Write_data(u8 Address , u8 Command,bool secureFlag)
{
	bool Parity=1;
	uint8_t sum=0;
	uint8_t SBC_WriteByte_H = 0;
	uint8_t i = 0;
	uint8_t SBC_WriteByte_L = 0;
	uint8_t SBC_Command_bit0 = 0;
	uint8_t SBC_Command_bit1 = 0;
	uint8_t SBC_Command_bit2 = 0;
	uint8_t SBC_Command_bit3 = 0;
	uint16_t SBCData = 0;
	uint16_t SBC_WriteWord = 0,Parity_data;
	/*组建命令高字节*/
	SBC_WriteByte_H = (uint8_t)(((Address << 1) | 0x80));
	/*组建命令低字节*/
	if(secureFlag == 1)
	{

		SBC_Command_bit0 = (Command&0x40)>>6;
		SBC_Command_bit1 = (Command&0x80)>>6;
		SBC_Command_bit2 = ((~Command) & 0x10)>>2;
		SBC_Command_bit3 = ((~Command) & 0x20)>>2;
		SBC_WriteByte_L = Command | SBC_Command_bit3 | SBC_Command_bit2 | SBC_Command_bit1 | SBC_Command_bit0;
	}
	else
	{
		SBC_WriteByte_L = Command;
	}

	Parity_data=SBC_WriteWord = (uint16_t)((SBC_WriteByte_H << 8) | SBC_WriteByte_L );


	 for(i = 0;i < 16;i++)
	 {
		if(i != 8){
		    sum = sum + (uint8_t)((Parity_data >> i) & 0x0001);
		}
	 }
	    if(sum%2 == 0){			//even number -> P = 1
	    	 SBC_WriteWord=SBC_WriteWord|0x0100;
	    }
	    else{
	    	SBC_WriteWord=SBC_WriteWord&0xFEFF;
	    }


	BSW_LPSPI_START(LPSPI0,SBC_WriteWord);
	SBCData=BSW_LPSPI_END(LPSPI0);
	return SBCData;
}

/*************************************************************************
 * Function Name	: SBC4500_Read_Command
 *
 * Description		: 读取SBC4500寄存器指令
 *
 * Input			: u8 Address
 *
 * Output			: uint16_t  SBCData
 *
 * Author			:
 *
 * Limitations		:
 *
 ************************************************************************/
uint16_t SBC4500_Read_data(u8 Address)
{
	uint8_t SBC_WriteByte_H = 0;
	uint16_t SBCData = 0;
	uint16_t SBC_WriteWord = 0;
	/*组建命令高字节*/
	SBC_WriteByte_H = (uint8_t)((Address << 1) & 0x7E);	/*清除最高位和校验位*/
	SBC_WriteWord = (uint16_t)((SBC_WriteByte_H << 8) & 0xFF00);/*清除低字节*/

	BSW_LPSPI_START(LPSPI0,SBC_WriteWord);
	SBCData=BSW_LPSPI_END(LPSPI0);
	return SBCData;
}



